home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / program / cgazv4n2.zip / DLFONT.C < prev    next >
C/C++ Source or Header  |  1989-10-27  |  16KB  |  440 lines

  1. /*--------------------------------------------------------------------*/
  2. /*                       D L F O N T . C                              */
  3. /*--------------------------------------------------------------------*/
  4. /* FILE:         DLFONT2.C                                            */
  5. /* DESCRIPTION:  Version 2 of the HP Font Downloading Program         */
  6. /* COMPILER(s):  Borland 2.0+, MS 5.0+, Zortech C/C++                 */
  7. /* AUTHOR:       Marv Luse, Ithaca Street Software, Inc.              */
  8. /* DATE:         Sept, 1989                                           */
  9. /* COPYRIGHT:    Use freely but acknowledge source.                   */
  10. /*--------------------------------------------------------------------*/
  11.  
  12. #include "stdlib.h"
  13. #include "stdio.h"
  14. #include "string.h"
  15. #include "dos.h"
  16.  
  17. #include "hpdesc.h"
  18.  
  19. /*--------------------------------------------------------------------*/
  20. /* Globally referenced variables...                                   */
  21. /*--------------------------------------------------------------------*/
  22.  
  23. char  *fnt_file,                 /* font file name */
  24.       *prt_port,                 /* printer port name */
  25.       *prt_def = "LPT1";         /* default printer port name */
  26.  
  27. FILE  *fnt_fp,                   /* font stream */
  28.       *prt_fp;                   /* printer stream */
  29.  
  30. int    font_id,                  /* font id number */
  31.        select_fnt,               /* flag - indicates select this font */
  32.        reset_prt,                /* flag - indicates reset printer */
  33.        is_perm,                  /* flag - indicates perm font */
  34.        cur_chr;                  /* ascii value of current char */
  35.  
  36. long   bytes_read,               /* read from font */
  37.        bytes_written;            /* sent to printer */
  38.  
  39. #define BUF_SIZ 512
  40. #define ESQ_SIZ 512
  41. char io_buf[BUF_SIZ],            /* file i/o bubber */
  42.      esq_buf[ESQ_SIZ+1],         /* escape seq holding area */
  43.      dld_chr[256];               /* flags - set ==> download */
  44.  
  45. /* macro to test for a capital letter - indicates end of sequence */
  46. #define  isCAP( c )  ( ((c>='A') && (c<='Z')) ? 1 : 0 )
  47.  
  48. /* macro to test for a digit */
  49. #define  isDIGIT( c )  ( ((c>='0') && (c<='9')) ? 1 : 0 )
  50.  
  51. /* escape sequence types to be processed */
  52. #define  UNUSED_SEQ  0     /* sequence ignored */
  53. #define  DEFINE_FNT  1     /* font descriptor */
  54. #define  DEFINE_CHR  2     /* char descriptor */
  55. #define  DEFINE_ASC  3     /* set char's ascii code */
  56.  
  57. /*--------------------------------------------------------------------*/
  58. /* Escape sequences...                                                */
  59. /*--------------------------------------------------------------------*/
  60.  
  61. char  *pRESET  = "\033E";          /* printer reset */
  62. char  *fPERM   = "\033*c5F";       /* make font permanent */
  63. char  *fSETID  = "\033*c???D";     /* set font id to ??? */
  64. char  *fSELECT = "\033(???X";      /* make font ??? primary */
  65.  
  66. /*--------------------------------------------------------------------*/
  67. /* Print a message and exit the pgm...                                */
  68. /*--------------------------------------------------------------------*/
  69.  
  70. void exit_pgm( int retc, char *msg )
  71.      {
  72.      printf( "\n%s", msg );
  73.      exit( retc );
  74.      }
  75.  
  76. /*--------------------------------------------------------------------*/
  77. /* Explain ourselves...                                               */
  78. /*--------------------------------------------------------------------*/
  79.  
  80. void explain_pgm( void )
  81.      {
  82.      printf( "\n" );
  83.      printf( "\nusage:      DLFONT  font_file  [prt_port]  [switches]" );
  84.      printf( "\n" );
  85.      printf( "\n            font_file  = path to an HP font file" );
  86.      printf( "\n            prt_port   = printer location (def = LPT1)" );
  87.      printf( "\n" );
  88.      printf( "\nswitches:   /In        = set font id to n (def = 1)" );
  89.      printf( "\n            /P         = make font permanent (def = temp)" );
  90.      printf( "\n            /R         = reset printer before download" );
  91.      printf( "\n            /S         = select font (make current)" );
  92.      printf( "\n            /{xxx}     = specify chars to download" );
  93.      }
  94.  
  95. /*--------------------------------------------------------------------*/
  96. /* Set variables and override from command line...                    */
  97. /*--------------------------------------------------------------------*/
  98.  
  99. void process_args( int argc, char *argv[] )
  100.      {
  101.      int   i, j;
  102.      char  sw, *swval;
  103.  
  104.      /* set defaults */
  105.      fnt_file   = NULL;
  106.      prt_port   = prt_def;
  107.      font_id    = 1;
  108.      is_perm    = 0;
  109.      reset_prt  = 0;
  110.      select_fnt = 0;
  111.      for( j = 0; j < 256; j++ )
  112.         dld_chr[j] = 1;
  113.  
  114.      /* inspect command line */
  115.      for( i = 1; i < argc; i++ )
  116.         {
  117.         if ( *argv[i] == '/' )           /* a switch */
  118.            {
  119.            sw    = *(argv[i] + 1);
  120.            swval =   argv[i] + 2;
  121.            switch( sw )
  122.                {
  123.                case 'i' :  /* set font id */
  124.                case 'I' :
  125.                     sscanf( swval, "%d", &font_id );
  126.                     break;
  127.                case 'p' :  /* make font permanent */
  128.                case 'P' :
  129.                     is_perm = 1;
  130.                     break;
  131.                case 'r' :  /* reset printer */
  132.                case 'R' :
  133.                     reset_prt = 1;
  134.                     break;
  135.                case 's' :  /* select font at printer */
  136.                case 'S' :
  137.                     select_fnt = 1;
  138.                     break;
  139.                case '{' :  /* specify chars to download */
  140.                     for( j = 0; j < 256; j++ )
  141.                          dld_chr[j] = 0;
  142.                     while( *swval && (*swval != '}') )
  143.                          dld_chr[*swval++] = 1;
  144.                     break;
  145.                }
  146.            }
  147.         else if ( fnt_file == NULL )     /* font file name */
  148.            fnt_file = argv[i];
  149.         else                             /* printer destination */
  150.            prt_port = argv[i];
  151.         }
  152.  
  153.      /* make sure we have a font name */
  154.      if ( fnt_file == NULL )
  155.         exit_pgm( 8, "Error - no font file name specified" );
  156.  
  157.      /* check for a valid font id */
  158.      if ( (font_id < 0) || (font_id > 999) )
  159.         exit_pgm( 8, "Error - specify font id in range 0-999" );
  160.      }
  161.  
  162. /*--------------------------------------------------------------------*/
  163. /* Use DOS function 44h (IOCTL) to set raw mode if a char device...   */
  164. /*--------------------------------------------------------------------*/
  165.  
  166. void set_binary_mode ( FILE *fptr )
  167.      {
  168.      int hand;
  169.      union REGS r;
  170.  
  171.      /* get file handle */
  172.      hand = fileno(fptr);
  173.  
  174.      /* get device info */
  175.      r.h.ah = 0x44;
  176.      r.h.al = 0x00;
  177.      r.x.bx = hand;
  178.      r.x.dx = 0;
  179.      int86(0x21, &r, &r);
  180.  
  181.      /* check the device... */
  182.      if ( (r.h.dl & 0x80) )         /* char device ? */
  183.         {
  184.         if ( ! (r.h.dl & 0x20) )    /* cooked mode ? */
  185.            {
  186.            r.h.ah  = 0x44;
  187.            r.h.al  = 0x01;
  188.            r.x.bx  = hand;
  189.            r.h.dh  = 0x00;
  190.            r.h.dl |= 0x20;          /* set raw mode */
  191.            int86(0x21, &r, &r);
  192.            }
  193.         }
  194.      }
  195.  
  196. /*--------------------------------------------------------------------*/
  197. /*  Open files, set device mode...                                    */
  198. /*--------------------------------------------------------------------*/
  199.  
  200. void open_files( void )
  201.      {
  202.      fnt_fp = fopen( fnt_file, "rb" );
  203.      if ( fnt_fp == NULL )
  204.         exit_pgm( 8, "Could not find font file" );
  205.      prt_fp = fopen( prt_port, "wb" );
  206.      if ( prt_fp == NULL )
  207.         exit_pgm( 8, "Error opening printer" );
  208.      set_binary_mode( prt_fp );
  209.      printf( "\ndownloading '%s' to '%s'...", fnt_file, prt_port );
  210.      }
  211.  
  212. /*--------------------------------------------------------------------*/
  213. /*  Close all files...                                                */
  214. /*--------------------------------------------------------------------*/
  215.  
  216. void close_files( void )
  217.      {
  218.      fclose( fnt_fp );
  219.      fclose( prt_fp );
  220.      printf( "done" );
  221.      }
  222.  
  223. /*--------------------------------------------------------------------*/
  224. /*  Send prefix escape sequences to the printer...                    */
  225. /*--------------------------------------------------------------------*/
  226.  
  227. void send_pfx( void )
  228.      {
  229.      /* if requested, reset printer */
  230.      if ( reset_prt )
  231.         if ( fwrite( pRESET, strlen(pRESET), 1, prt_fp ) != 1 )
  232.            exit_pgm( 8, "Error writing to printer" );
  233.  
  234.      /* set id for font to follow */
  235.      sprintf( fSETID, "\033*c%dD", font_id );
  236.      if ( fwrite( fSETID, strlen(fSETID), 1, prt_fp ) != 1 )
  237.         exit_pgm( 8, "Error writing to printer" );
  238.      }
  239.  
  240. /*--------------------------------------------------------------------*/
  241. /*  Send suffix escape sequences to the printer...                    */
  242. /*--------------------------------------------------------------------*/
  243.  
  244. void send_sfx( void )
  245.      {
  246.      /* if requested, make font permanent */
  247.      if ( is_perm )
  248.         if ( fwrite( fPERM, strlen(fPERM), 1, prt_fp ) != 1 )
  249.            exit_pgm( 8, "Error writing to printer" );
  250.  
  251.      /* if requested, make font the current font */
  252.      if ( select_fnt )
  253.         {
  254.         sprintf( fSELECT, "\033(%dX", font_id );
  255.         if ( fwrite( fSELECT, strlen(fSELECT), 1, prt_fp ) != 1 )
  256.            exit_pgm( 8, "Error writing to printer" );
  257.         }
  258.      }
  259.  
  260. /*--------------------------------------------------------------------*/
  261. /*  Send or Skip next n bytes from input...                           */
  262. /*--------------------------------------------------------------------*/
  263.  
  264. void send_n( int n, int send )
  265.      {
  266.      int nout;
  267.      while( n > 0 )
  268.           {
  269.           nout = (n > BUF_SIZ) ? BUF_SIZ : n;
  270.           n -= nout;
  271.           if ( fread(io_buf, 1, nout, fnt_fp) != nout )
  272.              exit_pgm( 8, "Unexpected EOF reading font file" );
  273.           if ( send )
  274.              if ( fwrite(io_buf, 1, nout, prt_fp) != nout )
  275.                 exit_pgm( 8, "Error writing to printer" );
  276.           bytes_read += nout;
  277.           bytes_written += (send) ? nout : 0;
  278.           }
  279.      }
  280.  
  281. /*--------------------------------------------------------------------*/
  282. /*  Send passed buffer to output...                                   */
  283. /*--------------------------------------------------------------------*/
  284.  
  285. void send_buf( char buf[], int nbytes )
  286.      {
  287.      if ( fwrite( buf, 1, nbytes, prt_fp ) != nbytes )
  288.           exit_pgm( 8, "Error writing to printer" );
  289.      bytes_written += nbytes;
  290.      }
  291.  
  292. /*--------------------------------------------------------------------*/
  293. /*  Determine esq type and its numeric argument...                    */
  294. /*--------------------------------------------------------------------*/
  295.  
  296. void get_esq_values( char esq_buf[], int *type, int *parm )
  297.      {
  298.      int i;
  299.      char  c1, c2, clast;
  300.  
  301.      /* determine type */
  302.      c1 = esq_buf[1];
  303.      c2 = esq_buf[2];
  304.      i = 0;
  305.      while( esq_buf[i] ) i++;
  306.      clast = esq_buf[i-1];
  307.      if ( (c1==')') && (c2=='s') && (clast=='W') )
  308.         *type = DEFINE_FNT;
  309.      else if ( (c1=='(') && (c2=='s') && (clast=='W') )
  310.         *type = DEFINE_CHR;
  311.      else if ( (c1=='*') && (c2=='c') && (clast=='E') )
  312.         *type = DEFINE_ASC;
  313.      else
  314.         *type = UNUSED_SEQ;
  315.  
  316.      /* get the numeric argument */
  317.      *parm = 0;
  318.      i     = 0;
  319.      while( (esq_buf[i]) && (! isDIGIT(esq_buf[i])) ) i++;
  320.      if ( isDIGIT(esq_buf[i]) )
  321.         sscanf( esq_buf+i, "%d", parm );
  322.      }
  323.  
  324. /*--------------------------------------------------------------------*/
  325. /*  Process the escape seq now in the buffer...                       */
  326. /*--------------------------------------------------------------------*/
  327.  
  328. void do_esq( char esq_buf[] )
  329.      {
  330.      int esq_type, esq_parm;
  331.  
  332.      /* get the escape sequence type and the imbedded numeric value */
  333.      get_esq_values( esq_buf, &esq_type, &esq_parm );
  334.  
  335.      bytes_read += strlen( esq_buf );
  336.  
  337.      /* process the sequence */
  338.      switch( esq_type )
  339.            {
  340.            case DEFINE_FNT:  /* font descriptor */
  341.                 /* send the sequence */
  342.                 send_buf( esq_buf, strlen(esq_buf) );
  343.                 /* send the descriptor */
  344.                 send_n( esq_parm, 1 );
  345.                 break;
  346.            case DEFINE_CHR:  /* char descriptor */
  347.                 if ( dld_chr[cur_chr] )
  348.                    {
  349.                    /* send the sequence */
  350.                    send_buf( esq_buf, strlen(esq_buf) );
  351.                    /* send the descriptor */
  352.                    send_n( esq_parm, 1 );
  353.                    }
  354.                 else
  355.                    /* skip the descriptor */
  356.                    send_n( esq_parm, 0 );
  357.                 break;
  358.            case DEFINE_ASC:  /* specify character code */
  359.                 cur_chr = esq_parm;
  360.                 /* send the sequence */
  361.                 if ( dld_chr[cur_chr] )
  362.                    send_buf( esq_buf, strlen(esq_buf) );
  363.                 break;
  364.            case UNUSED_SEQ:  /* unknown sequence - ignore it */
  365.                 break;
  366.            }
  367.      }
  368.  
  369. /*--------------------------------------------------------------------*/
  370. /*  Read the next esc seq from the font file...                       */
  371. /*--------------------------------------------------------------------*/
  372.  
  373. int get_esq( char esq_buf[], int buf_len )
  374.     {
  375.     int i, nbytes;
  376.     nbytes = 0;
  377.     while( (i=fgetc(fnt_fp)) != EOF )
  378.          {
  379.          esq_buf[nbytes] = (char) i;
  380.          nbytes++;
  381.          /* capital letter signals last character in sequence */
  382.          if ( isCAP( i ) ) break;
  383.          if ( nbytes == buf_len )
  384.             exit_pgm( 8, "Error - escape sequence buffer overflow" );
  385.          }
  386.     /* validity check - first character should be decimal 27 */
  387.     if ( (nbytes > 0) && (esq_buf[0] != 27) )
  388.          exit_pgm( 8, "Error - escape sequence expected but not found" );
  389.     /* add a terminating null */
  390.     esq_buf[nbytes] = 0;
  391.     return( nbytes );
  392.     }
  393.  
  394. /*--------------------------------------------------------------------*/
  395. /*  Send the font file to the printer...                              */
  396. /*--------------------------------------------------------------------*/
  397.  
  398. void send_fnt( void )
  399.      {
  400.      while( get_esq( esq_buf, ESQ_SIZ ) > 0 )
  401.           do_esq( esq_buf );
  402.      }
  403.  
  404. /*--------------------------------------------------------------------*/
  405. /*                          M  A  I  N                                */
  406. /*--------------------------------------------------------------------*/
  407.  
  408. void main ( int argc, char *argv[] )
  409.      {
  410.      char msg[80];
  411.  
  412.      /* sign on */
  413.      printf("\n---- HP Font File Download Utility");
  414.  
  415.      /* enough args ? */
  416.      if ( (argc < 2) || (*(argv[1]) == '?') )
  417.         {
  418.         explain_pgm();
  419.         exit_pgm( 0, "" );
  420.         }
  421.  
  422.      /* set values from command line */
  423.      process_args( argc, argv );
  424.  
  425.      /* init counters */
  426.      bytes_read    = 0;
  427.      bytes_written = 0;
  428.  
  429.      /* do the download... */
  430.      open_files();
  431.      send_pfx();
  432.      send_fnt();
  433.      send_sfx();
  434.      close_files();
  435.  
  436.      /* summarize activity */
  437.      sprintf( msg, "%ld bytes downloaded out of %ld bytes read",
  438.                    bytes_written, bytes_read );
  439.      exit_pgm( 0, msg );
  440.      }